/*
 * Created on Feb 15, 2005
 * Created by dfhuynh
 */
package edu.mit.simile.longwell.ui;

import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.vocabulary.RDF;

import edu.mit.simile.longwell.IStructuredModel;
import edu.mit.simile.longwell.Profile;
import edu.mit.simile.longwell.StructuredModelBase;
import edu.mit.simile.longwell.schema.ISchemaModel;

/**
 * @author dfhuynh
 */
public class FlairStructuredModel 
	extends StructuredModelBase implements IStructuredModel {

	final static public String s_flair_shortLabel = Flair.s_namespace + "shortLabel";
	final static public String s_flair_contentDescription = Flair.s_namespace + "contentDescription";
	final static public String s_flair_Facade = Flair.s_namespace + "Facade";
	final static public String s_flair_SchemaBasedFacade = Flair.s_namespace + "SchemaBasedFacade";
	final static public String s_flair_QueryBasedFacade = Flair.s_namespace + "QueryBasedFacade";
	
	final static private Logger s_logger =
		Logger.getLogger(FlairStructuredModel.class);

	protected boolean 	m_initialized;
	protected Map		m_facades = new HashMap();

	/**
	 * @param modelURI
	 * @param profile
	 * @param dir
	 */
	public FlairStructuredModel(Profile profile, File dir) {
		super(profile, dir);
	}

	/* (non-Javadoc)
	 * @see edu.mit.simile.longwell.model.IStructuredModel#dispose()
	 */
	public void dispose() {
	}

	public Set getFacades() {
		internalInitialize();

		return new HashSet(m_facades.values());
	}

	protected void internalInitialize() {
		if (m_initialized) {
			return;
		}
		
		internalOnAfterAdd(m_profile.getModel());

		m_initialized = true;
	}

	/* (non-Javadoc)
	 * @see edu.mit.simile.longwell.IProfileListener#onAfterAdd(com.hp.hpl.jena.rdf.model.Model)
	 */
	public void onAfterAdd(Model model) {
		super.onAfterAdd(model);
		
		internalInitialize();
		internalOnAfterAdd(model);
	}
	
	public void internalOnAfterAdd(Model model) {
		ISchemaModel schemaModel = m_profile.getSchemaModel();

		ResIterator ri = model.listSubjectsWithProperty(
				RDF.type, model.createResource(s_flair_SchemaBasedFacade));
		while (ri.hasNext()) {
			Resource r = ri.nextResource();

			String shortLabel = tryGetStringProperty(
				model, r, model.createProperty(s_flair_shortLabel), r.getURI());
			String contentDescription = tryGetStringProperty(
				model, r, model.createProperty(s_flair_contentDescription), "");
			
			m_facades.put(r.getURI(),
				SchemaBasedFacade.constructFacade(
					r, shortLabel, contentDescription, model, m_profile));
		}
		
		ri = model.listSubjectsWithProperty(
				RDF.type, model.createResource(s_flair_QueryBasedFacade));
		while (ri.hasNext()) {
			Resource r = ri.nextResource();

			String shortLabel = tryGetStringProperty(
				model, r, model.createProperty(s_flair_shortLabel), r.getURI());
			String contentDescription = tryGetStringProperty(
				model, r, model.createProperty(s_flair_contentDescription), "");
			
			m_facades.put(r.getURI(),
				QueryBasedFacade.constructFacade(
					r, shortLabel, contentDescription, model, m_profile));
		}
	}

	/* (non-Javadoc)
	 * @see edu.mit.simile.longwell.IProfileListener#onAfterRemove(com.hp.hpl.jena.rdf.model.Model)
	 */
	public void onAfterRemove(Model model) {
		ResIterator ri = model.listSubjectsWithProperty(
				RDF.type, model.createResource(s_flair_Facade));
		while (ri.hasNext()) {
			Resource r = ri.nextResource();

			m_facades.remove(r.getURI());
		}
	}
	
	protected String tryGetStringProperty(
			Model model, Resource r, Property p, String defaultValue) {
		try {
			return model.getProperty(r, p).getString();
		} catch (Exception e) {
			return defaultValue;
		}
	}
}
